package v2;

import java.util.ArrayList;
/**
 * 
 */

/**
 * La Classe representant les positions de différentes parcelles du Terrain.
 * 
 * @author bosc & dunoyerd
 * @version 0.1
 * @see 
 * @since version 0.1
 */
public class Position {
	
	
	// Attributs
	
	/**
	 * L'abscisse de la position. la ligne n'est pas modifiable.
	 * 
	 * @see Position#Position(int,int)
	 */
	private final int ligne;
	
	/**
	 * L'ordonnée de la position. la colonne n'est pas modifiable.
	 * 
	 * @see Position#Position(int,int)
	 */
	private final int colonne;
	
	// Constructeurs
	
	/**
	 * Represente les lignes et les colonnes
	 * 
	 * @param ligne
	 * 		represente la ligne
	 * @param colonne
	 * 		represente la colonne
	 * @see Position#ligne
	 * @see Position#colonne
	 */
	public Position(int ligne, int colonne)
	{
		this.ligne = ligne;
		this.colonne = colonne;
	}
	
	// Accesseurs
	
	/**
	 * Retourne l'abscisse de la Position.
	 * 
	 * @return la ligne
	 */
	public int obtientLigne()
	{
		return this.ligne;
	}
	
	/**
	 * Retourne l'ordonnée de la position
	 * 
	 * @return la colonne
	 */
	public int obtientColonne()
	{
		return this.colonne;
	}
	
	// Méthodes
	
	/**
	 * Retourne la représentation de la position sous forme de chaine de caractères
	 * 
	 * @return ma description de la Position
	 * 
	 */
	public String toString()
	{
		return " ma ligne: "+this.ligne+" ma colonne: "+this.colonne+" ";
	}
	
	/**
	 * Test d'égalité de la position sur ligne et colonne
	 * 
	 * @return un booléen
	 */
	public boolean equals(Object monObjet)
	{
		if (monObjet instanceof Position)
		{
			Position maPosition = (Position) monObjet;
			return this.ligne == maPosition.obtientLigne() && this.colonne == maPosition.obtientColonne();
		}
		return false;
	}
	
	/**
	 * Methode permettant de calculer la distance entre 2 positions
	 * abondement utilisée
	 * 
	 * @param maPos1 ma premiere position
	 * @param maPos2 ma seconde position
	 * @return la distance entre les 2 positions
	 */
	public static double calculDistance(Position maPos1, Position maPos2)
	{
		return OutilsMathematiques.dist2Points(maPos1.obtientLigne(), maPos1.obtientColonne(), maPos2.obtientLigne(), maPos2.obtientColonne());
	}
	
	/**
	 * Permet de déterminer si deux positions sont contigues
	 * utilisée partout dans Animaux
	 * 
	 * @param maPos la position dont je veux savoir si elle est contigue
	 * @return si oui ou non les 2 positions sont contigues
	 */
	public boolean estContigue(Position maPos)
	{
		if (((maPos.obtientLigne() < this.obtientLigne()+2) && (maPos.obtientLigne() > this.obtientLigne()-2)) && ((maPos.obtientColonne() < this.obtientColonne()+2) && (maPos.obtientColonne() > this.obtientColonne()-2)))
		{
			return true;
		}
		return false;
	}
	
	/**
	 * Méthode permettant de calculer une position relative en soustrayant les coordonnées des positions
	 * utilisé par Animaux.fuitePredateur(...)
	 * 
	 * @param: monCentre
	 * @param: maPeripherie
	 * @return 
	 */
	public static Position calculPositionRelative(Position monCentre, Position maPeripherie)
	{
		return new Position(monCentre.obtientLigne()-maPeripherie.obtientLigne(),monCentre.obtientColonne()-maPeripherie.obtientColonne());
	}
	
	/**
	 * Méthode permettant de calculer une position "propotionellement" à un facteur. 
	 * utilisé par Animaux.fuitePredateur(...)
	 * 
	 * @param maPosition: ma position originale
	 * @param monFacteur: la facteur par lequel multuiplié ma position
	 * @return ma position calculée
	 */
	public static Position calculcalculPositionProportionelle(Position maPosition, int monFacteur)
	{
		return new Position(maPosition.obtientLigne()*monFacteur,maPosition.obtientColonne()*monFacteur);
	}
	
	/**
	 * Méthode permettant de calculer la position inverse de la position d'entrée:
	 * on inverse les lignes et les colonnes
	 * utilisé par Animaux.fuitePredateur(...)
	 * 
	 * @param maPositionInit: la position dont je cherche a calculer la position inverse
	 * @return le position "inverse" (ligne devient colonne et inversement)
	 */
	public static Position calculPositionInverse(Position maPositionInit)
	{
		return new Position(maPositionInit.obtientLigne(),maPositionInit.obtientColonne());
	}
	
	
	/**
	 * Méthode permettant de calculer une position moyenne a partr d'une ArrayList de Position
	 * Utilisée par Animaux.fuitePredateurs(...)
	 * 
	 * @param mesPos: l'arraylist de positions à partir de laquelle je cherche à calculer la position moyenne
	 */
	public static Position calculPositionMoyenne(ArrayList<Position> mesPos)
	{
		// mes valeur
		int lignes = 0;
		int colonnes = 0;
		
		// addition coordonnées relatives...
		for (int i = 0; i<mesPos.size();i++)
		{
			lignes = mesPos.get(i).obtientLigne();
			colonnes = mesPos.get(i).obtientColonne();
		}
		
		//moyenne
		lignes = lignes / mesPos.size();
		colonnes = colonnes / mesPos.size();
		
		//renvoi de la position
		return new Position(lignes,colonnes);
	}
	
	
	/**
	 * Méthode permettant de trouver la plus proche parcelle par rapport à une position
	 * 
	 * @param mesParcLibAccContig la liste des parcelles contigues et accessibles
	 * @return ma parcelle la plus proche de ma position
	 */
	public Parcelle calculPositionFuite(ArrayList<Parcelle> mesParcLibAccContig)
	{
		if (mesParcLibAccContig.size() == 0)
		{
			return null;
		}
		
		Parcelle maParcProche = mesParcLibAccContig.get(0);
		double distance = Position.calculDistance(this, maParcProche.obtientMaPosition());
		
		for (int i = 1; i<mesParcLibAccContig.size();i++)
		{
			double distTemp = Position.calculDistance(this,mesParcLibAccContig.get(i).obtientMaPosition());
			if(distTemp < distance)
			{
				distance = distTemp;
				maParcProche = mesParcLibAccContig.get(i);
			}
		}
		return maParcProche;
		
		/* ANCIENNE METHODE
		// je détermine l'équation de la droite... FAUUUUUUUUUUUUUUUUUX
		int a = maPos.obtientColonne()/maPos.obtientLigne();
		int b = this.obtientPosition().obtientColonne()-a*this.obtientPosition().obtientLigne();
		// je cherche le point qui minimise la distance avec la droite y = coef * x
		if (mesParcLibAccContig.size() == 0)
		{
			return null;
		}
		else
		{
			Parcelle maParcFinale = mesParcLibAccContig.get(0);
			double yMin = Math.abs(a*maParcFinale.obtientMaPosition().obtientLigne()+b);
			for (int i=1;i<mesParcLibAccContig.size();i++)
			{
				// Je choisi le point qui minimise l'ordonnée
				if(Math.abs(a*mesParcLibAccContig.get(i).obtientMaPosition().obtientLigne()+b)<yMin)
				{
					maParcFinale = mesParcLibAccContig.get(i);
				}
			}
			return maParcFinale;
		}*/
	}
}

	

